這裡將利用教程所提供的"Treasure Hunter Game"來直接學習PixiJS中的語法。"Treasure Hunter Game"的程式碼 ---> Click Here !
系統提示:「Success grows out of struggles to overcome difficulties.」,PixiJS青銅玩家仍卡關在play()階段僅獲得經驗提昇等級。
泡泡怪們的移動並不是由玩家操控,因此我們需要製作一個循環機制,使泡泡怪們可以自行的上下移動,讓玩家去閃躲。
blobs.forEach(function(blob) {
blob.y += blob.vy;
let blobHitsWall = contain(blob, {x: 28, y: 10, width: 488, height: 480});
if (blobHitsWall === "top" || blobHitsWall === "bottom") {
blob.vy *= -1;
}
if(hitTestRectangle(explorer, blob)) {
explorerHit = true;
}
});
這裡的blobs為一個陣列,在【LV. 12】中曾經提過,我們在setup()
函式中,將創建好的泡泡怪的Sprite一一推進blobs陣列中。
而此處就是當初推進blobs陣列的用意,因為每個泡泡怪的運動行為模式是一樣的,所以我們只須利用陣列的特性,對陣列的內容依序去執行動作,也因此只須一次程式即可完成,而非對各個泡泡怪都各執行一次。
blobs.forEach(function(blob) {
...
}
for loop VS. forEach
這裡稍微試著去理解兩者的差異,一般來說forEach的功能跟for loop很像,都是對一個陣列的內容一一去取值的動作。
以上方例子來說,若利用for loop寫法則變成:
for(let i = 0; i < blobs.length; i++){
blobs[i].y += blob[i].vy;
...
...
}
相較之下,for loop寫法稍嫌麻煩了,不過for loop可以搭配break,在迴圈當中把程式給中斷,且forEach並非所有陣列皆可以使用,例如說類陣列就沒有辦法使用forEach去運行。
PS 類陣列利用forEach還是有辦法的,可以利用「展開」語法,將類陣列轉換成純陣列去使用即可(如下)。
let array = [...arrayLike];
array.forEach(i=>console.log(i));
***
接著看到forEach()裡頭的內容,首先就是處理泡泡怪移動的速度。
blob.y += blob.vy;
而其中的blob.vy一樣在【LV. 12】時就提到,泡泡怪們的移動速度是利用speed為2去乘上direction方向,也就是說泡泡怪他們是以每幀2px向下或向上去移動的(至於向下或向上,取決於direction為+1或是-1),程式碼如下(回顧一下):
blob.vy = speed * direction;
direction *= -1;
再來是在昨天【LV. 17】提到的自定義函式contain()
,昨天是運用在不要讓explorer跑出地牢之外,而今天利用了contain()
幫助我們達到兩件事情:
let blobHitsWall = contain(blob, {x: 28, y: 10, width: 488, height: 480});
再來是【LV. 17】沒有提到的部份,contain()
這個函式回return一個叫做collision的值,而他的值會依第一個參數碰撞到第二個參數的上邊、下邊、左邊或右邊給予回傳值,分別為top、bottom、left、right,而如果碰撞並未發生,則collision則return undefined。
藉此來判斷當泡泡怪碰到下邊或上邊時,就得使他的移動方向反方向,而這裡只需要透過正負號即可轉換往上或往下的動作。
if (blobHitsWall === "top" || blobHitsWall === "bottom") {
blob.vy *= -1;
}
來到最後,便是偵測explorer是否與blob相撞,因為explorer與blob相撞的話會扣血,因此我們必須有個程式去判斷,而這裡便又是利用到了一個自定義函式,稱作hitTestRectangle()
。
一樣先不談程式碼(若有需要,這裡附上官方教程碰撞偵測函數的電梯)
但可以先知道的是hitTestRectangle()
具有兩個參數,而參數便是兩個不同的Sprite,當這兩個不同的Sprite相碰相撞時,這個函式會回傳true
,以便使我們做判斷他們兩者是否有接觸。
因此底下程式碼的意思,就是當explorer與blob相撞了,這個時候我們必須使explorerHit
這變數賦值為true
。
if(hitTestRectangle(explorer, blob)) {
explorerHit = true;
}
});
今天先將泡泡怪們的移動以及碰撞偵測寫完!明天或許能把play()
以及end()
給結束。